package com.example.foo.api.web.member;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

import com.ruoyi.common.core.domain.AjaxResult;
import com.example.core.PageResult;
import com.example.core.Pageable;
import com.example.foo.account.model.Account;
import com.example.foo.account.service.AccountService;
import com.example.foo.api.boot.TokenHelper;
import com.example.foo.ftt.model.FttUser;
import com.example.foo.ftt.service.FttUserService;
import com.example.foo.member.model.MemberBankcard;
import com.example.foo.member.model.MemberIdcard;
import com.example.foo.member.model.Withdraw;
import com.example.foo.member.query.WithdrawQuery;
import com.example.foo.member.service.MemberBankcardService;
import com.example.foo.member.service.MemberIdcardService;
import com.example.foo.member.service.WithdrawFacadeService;
import com.example.foo.member.service.WithdrawService;
import com.example.support.redis.RedisHelper;
import com.example.util.RegexSnippetUtils;

@org.springframework.web.bind.annotation.RestController
public class WithdrawAction {

	private final AccountService accountService;
	private final MemberIdcardService memberIdcardService;
	private final MemberBankcardService memberBankcardService;
	private final FttUserService fttUserService;
	private final WithdrawService withdrawService;
	private final WithdrawFacadeService withdrawFacadeService;

	public WithdrawAction(AccountService accountService,
			MemberIdcardService memberIdcardService,
			MemberBankcardService memberBankcardService,
			FttUserService fttUserService,
			WithdrawService withdrawService,
			WithdrawFacadeService withdrawFacadeService) {
		this.accountService = accountService;
		this.memberIdcardService = memberIdcardService;
		this.memberBankcardService = memberBankcardService;
		this.fttUserService = fttUserService;
		this.withdrawService = withdrawService;
		this.withdrawFacadeService = withdrawFacadeService;
	}

	@GetMapping("/api/withdraws")
	public AjaxResult index(WithdrawQuery withdrawQuery, Pageable pageable) {
		Long userId = TokenHelper.verifyToken();
		if (!Objects.equals(userId, withdrawQuery.getUserId())) {
			return AjaxResult.error(403, "Access Forbidden");
		}
		PageResult<Withdraw> pageResult = withdrawService.findWithdraws(withdrawQuery, pageable);
		return AjaxResult.successData(pageResult);
	}

	@GetMapping("/api/withdraws/{id}")
	public AjaxResult showWithdraw(@PathVariable("id") Long id) {
		Long userId = TokenHelper.verifyToken();
		Withdraw withdraw = withdrawService.findWithdrawById(id);
		if (withdraw == null) {
			return AjaxResult.error(404, "Not Found");
		}
		if (!Objects.equals(userId, withdraw.getUserId())) {
			return AjaxResult.error(403, "Access Forbidden");
		}
		return AjaxResult.successData(withdraw);
	}

	@PostMapping("/api/withdraws")
	public AjaxResult createWithdraw(Withdraw withdrawForm) {
		//
		String bankName;// = withdrawForm.getBankName();
		String bankBranchName;// = withdrawForm.getBankBranchName();
		String cardHolder;// = withdrawForm.getCardHolder();
		String cardNumber;// = withdrawForm.getCardNumber();
		BigDecimal money = withdrawForm.getMoney();

		//
		//if (StringUtils.isBlank(bankName)) {
		//	return AjaxResult.error(400, "bankName must not be null");
		//}
		//if (StringUtils.isBlank(bankBranchName)) {
		//	return AjaxResult.error(400, "bankBranchName must not be null");
		//}
		//if (StringUtils.isBlank(cardHolder)) {
		//	return AjaxResult.error(400, "cardHolder must not be null");
		//}
		//if (StringUtils.isBlank(cardNumber)) {
		//	return AjaxResult.error(400, "cardNumber must not be null");
		//}
		if (money == null) {
			return AjaxResult.error(400, "money must not be null");
		}
		if (money.compareTo(BigDecimal.ZERO) <= 0 || money.remainder(BigDecimal.TEN).compareTo(BigDecimal.ZERO) != 0) {
			return AjaxResult.error(400, "请输入10的倍数");
		}

		//
		Long userId = TokenHelper.verifyToken();

		//
		String lockKey = String.format("lock:withdraw:userId_%s", userId);
		if (!RedisHelper.setnxex(lockKey, 15, "-")) {
			return AjaxResult.error(400, "操作频繁，请稍后");
		}

		//
		LocalDateTime now = LocalDateTime.now();
		LocalDate today = now.toLocalDate();
		int hour = now.toLocalTime().getHour();

		//
		if (hour >= 9 && hour < 21) {
			//NOOP
		} else {
			return AjaxResult.error(400, "提现时间 9:00--21:00");
		}

		//
		FttUser fttUser = fttUserService.findFttUserByUserId(userId);
		/*if (fttUser.getCardzState() == FttUser.CardzState.pending) {
			return AjaxResult.error(400, "需要您先开通套餐，才能享受申请提现。");
		} else if (fttUser.getCardzState() == FttUser.CardzState.failure) {
			return AjaxResult.error(400, String.format("您的【%s】卡号现在已欠费，请保证正常缴费，才能解除提现限制；补缴成功后，方可提现。", RegexSnippetUtils.desensitizeCellphone_CN(fttUser.getCardzCellphone())));
		}*/

		if (fttUser!=null&&fttUser.getState() != FttUser.State.normal) {
			return AjaxResult.error(400, "您的账号已冻结，无法提现。");
		}

		//
		MemberIdcard memberIdcard = memberIdcardService.findMemberIdcardByUserId(userId);
		if (memberIdcard.getState() != MemberIdcard.State.success) {
			return AjaxResult.error(400, "请先实名认证");
		}

		//
		List<MemberBankcard> memberBankcards = memberBankcardService.findMemberBankcardsByUserId(userId);
		if (memberBankcards.isEmpty()) {
			return AjaxResult.error(400, "请先绑定银行卡");
		}
		MemberBankcard memberBankcard = memberBankcards.get(0);
		if (memberBankcard.getState() != MemberBankcard.State.success) {
			return AjaxResult.error(400, "请确认银行卡绑定是否成功");
		}
		bankName = memberBankcard.getBankName();
		bankBranchName = memberBankcard.getBankBranchName();
		cardHolder = memberBankcard.getCardHolder();
		cardNumber = memberBankcard.getCardNumber();

		//
		Account.Acctc acctc = Account.Acctc.pinmoney;
		Account account = accountService.findAccountBalance(acctc, userId);
		if (account.getTotal().compareTo(money) < 0) {
			return AjaxResult.error(400, "余额不足");
		}

		//
		Withdraw withdraw = withdrawService.findWithdrawLatestByUserId(userId);
		if (withdraw != null) {
			if (withdraw.getState() == Withdraw.State.pending) {
				return AjaxResult.error(400, "还有一笔提现正在处理中");
			}
			if (withdraw.getCreatedAt().toLocalDate().toEpochDay() == today.toEpochDay()) {
				return AjaxResult.error(400, "已达到今日提现次数上限");
			}
		}

		//
		BigDecimal serviceFee = money.multiply(new BigDecimal("0.06"));
		withdrawFacadeService.createWithdrawPending(bankName, bankBranchName, cardHolder, cardNumber, money, serviceFee, userId);

		return AjaxResult.success();
	}

}
